package com.vca.service.service.Impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.vca.common.constants.CategoryConstants;
import com.vca.common.exception.VcaException;
import com.vca.common.model.category.Category;
import com.vca.common.model.course.*;
import com.vca.common.request.AdminCommonRequest;
import com.vca.common.request.CourseAboutAddRequest;
import com.vca.common.request.CoursePackageAddRequest;
import com.vca.common.request.PageParamRequest;
import com.vca.common.response.AdminHeaderResponse;
import com.vca.common.response.CourseAboutAdminResponse;
import com.vca.common.response.CoursePackageAdminListResponse;
import com.vca.common.response.CoursePackageAdminResponse;
import com.vca.common.utils.PageUtils;
import com.vca.service.dao.course.CoursePackageDao;
import com.vca.service.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 套课表 服务实现类
 * </p>
 *
 * @author chenBing
 * @since 2022-11-16
 */
@Service
@Slf4j
public class CoursePackageServiceImpl extends ServiceImpl<CoursePackageDao, CoursePackage> implements CoursePackageService {

    @Resource
    private CoursePackageDao dao;

    @Autowired
    private SystemGroupDataService systemGroupDataService;

    @Autowired
    private CourseInfoService courseInfoService;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private SystemAttachmentService systemAttachmentService;

    @Autowired
    private CourseAboutService courseAboutService;

    @Autowired
    private CourseService courseService;

    @Autowired
    private ExhibitionService exhibitionService;

    @Autowired
    private TalkService talkService;

    @Autowired
    private VcaProductService vcaProductService;

    @Autowired
    private CoursePackageRelationService coursePackageRelationService;

    @Autowired
    private CourseSchedulingService courseSchedulingService;

    @Autowired
    private CategoryService categoryService;



    /**
     * 套课列表
     *
     * @param request
     * @param pageParamRequest
     * @return
     * @author Li
     * @date 2022/11/17 17:15
     */
    @Override
    public PageInfo getAdminList(AdminCommonRequest request, PageParamRequest pageParamRequest) {
        List<CoursePackageAdminListResponse> courseAdminList = new ArrayList<>();
        LambdaUpdateWrapper<CoursePackage> wrapper = new LambdaUpdateWrapper();
        wrapper.eq(CoursePackage::getIsDeleted, 0);
        if (ObjectUtil.isNotEmpty(request.getType())) {
            wrapper.eq(CoursePackage::getCourseTypeId, request.getType());
        }
        if (ObjectUtil.isNotEmpty(request.getDuration())) {
            wrapper.eq(CoursePackage::getDurationTotal, request.getDuration());
        }
        if (ObjectUtil.isNotEmpty(request.getPrice())) {
            wrapper.eq(CoursePackage::getCoursePackagePriceId, request.getPrice());
        }
        if (ObjectUtil.isNotEmpty(request.getStatus())) {
            wrapper.eq(CoursePackage::getStatus, request.getStatus());
        }
        if (ObjectUtil.isNotEmpty(request.getKeywords())) {
            List<Integer> ids = dao.fuzzySearch(request.getKeywords());
            if (ObjectUtil.isEmpty(ids)) {
                return PageUtils.startPage(courseAdminList, pageParamRequest.getPage(), pageParamRequest.getLimit());
            }
            wrapper.in(CoursePackage::getId, ids);
        }
        List<Category> categories = categoryService.list(new LambdaQueryWrapper<Category>().eq(Category::getType, CategoryConstants.CATEGORY_TYPE_COURSE));
        Map<String,List<HashMap<String, Object>>> courseAdminConfig = systemGroupDataService.getCourseAdminConfig();
        Map<String, List> courseSchedulingAdminConfig = systemGroupDataService.getCourseSchedulingAdminConfig();
        List languageList = courseSchedulingAdminConfig.get("languageList");
        List<HashMap<String, Object>> price = courseAdminConfig.get("priceList");
        List<HashMap<String, Object>> address = courseAdminConfig.get("addressList");

        List<CoursePackage> courses = dao.selectList(wrapper);
        courses.forEach(course -> {
            CoursePackageAdminListResponse response = new CoursePackageAdminListResponse();
            BeanUtils.copyProperties(course, response);
            response.setDetails(course.getDetails());
            //获得套课关联的课程id列表
            List<Long> courseIds = coursePackageRelationService.list(new LambdaQueryWrapper<CoursePackageRelation>().eq(CoursePackageRelation::getCoursePackageId, course.getId())).stream().map(CoursePackageRelation::getCourseId).collect(Collectors.toList());
            StringBuilder stringBuilder=new StringBuilder();
            List<String> languageIds=new ArrayList<>();
            Map<String, String> language=new HashMap<>();
            //遍历课程的排期语言
            courseIds.forEach(e->{
                Course courseOne = courseService.getOne(new LambdaQueryWrapper<Course>().eq(Course::getId, e).eq(Course::getIsDeleted,0));
                if (ObjectUtil.isNotEmpty(courseOne)){
                    List<CourseScheduling> schedulings = courseSchedulingService.list(new LambdaQueryWrapper<CourseScheduling>().eq(CourseScheduling::getCourseId, courseOne.getId()).eq(CourseScheduling::getIsDel,0));
                    if (ObjectUtil.isNotEmpty(schedulings)) {
                        schedulings.forEach(g->{
                            languageList.forEach(l->{
                                Map map = JSON.parseObject(JSONObject.toJSONString(l), Map.class);
                                if (map.get("id").equals(g.getCourseLanguageId())) {
                                    language.put(map.get("id").toString(),map.get("courseLanguage").toString());
                                }
                            });
                        });
                    }
                }
            });
            //添加语言
            language.forEach((k,v)->{
                if (ObjectUtil.isEmpty(stringBuilder)){
                    stringBuilder.append(v);
                }else {
                    stringBuilder.append(","+v);
                }
                languageIds.add(k);
            });
            response.setCourseLanguage(stringBuilder.toString());
            price.forEach(e -> {
                Map map = JSON.parseObject(JSONObject.toJSONString(e), Map.class);
                if (map.get("id").equals(course.getCoursePackagePriceId())) {
                    response.setPrice(map.get("coursePrice").toString());
                }
            });
            address.forEach(e -> {
                Map map = JSON.parseObject(JSONObject.toJSONString(e), Map.class);
                if (map.get("id").equals(course.getCourseAddressId())) {
                    response.setCourseAddress(map.get("courseAddress").toString() + map.get("courseAddressInfo").toString());
                }
            });
            categories.forEach(e->{
                if (e.getId().equals(course.getCourseTypeId())){
                    response.setCourseType(e.getName());
                }
            });
            if (ObjectUtil.isNotEmpty(request.getLanguageId())){
                List<String> languageId = languageIds.stream().filter(e -> e.equals(request.getLanguageId().toString())).collect(Collectors.toList());
                if (ObjectUtil.isNotEmpty(languageId)){
                    courseAdminList.add(response);
                }
            }else {
                courseAdminList.add(response);
            }
        });
        courseAdminList.sort(Comparator.comparing(CoursePackageAdminListResponse::getSort).reversed());
        return PageUtils.startPage(courseAdminList, pageParamRequest.getPage(), pageParamRequest.getLimit());
    }

    /**
     * 修改排序
     *
     * @param coursePackageId 套课id
     * @param sort            排序
     * @return
     * @author Li
     * @date 2022/11/18 09:36
     */
    @Override
    public boolean updateSort(Integer coursePackageId, Integer sort) {
        LambdaQueryWrapper<CoursePackage> wrapper=new LambdaQueryWrapper();
        wrapper.eq(CoursePackage::getId, coursePackageId);
        wrapper.eq(CoursePackage::getIsDeleted,0);
        CoursePackage coursePackage = dao.selectOne(wrapper);
        if (ObjectUtil.isEmpty(coursePackage)){
            throw new VcaException("该套课不存在");
        }
        coursePackage.setSort(sort);
        return transactionTemplate.execute(e->{
            dao.updateById(coursePackage);
            return Boolean.TRUE;
        });
    }

    /**
     * 上架课程
     *
     * @param coursePackageId 套课id
     * @return
     * @author Li
     * @date 2022/11/18 09:36
     */
    @Override
    public boolean courseOnShell(Integer coursePackageId) {
        LambdaQueryWrapper<CoursePackage> wrapper=new LambdaQueryWrapper();
        wrapper.eq(CoursePackage::getId, coursePackageId);
        wrapper.eq(CoursePackage::getIsDeleted,0);
        CoursePackage coursePackage = dao.selectOne(wrapper);
        if (ObjectUtil.isEmpty(coursePackage)){
            throw new VcaException("该套课不存在");
        }
        coursePackage.setStatus(1);
        return transactionTemplate.execute(e->{
            dao.updateById(coursePackage);
            return Boolean.TRUE;
        });
    }

    /**
     * 下架课程
     *
     * @param coursePackageId 套课id
     * @return
     * @author Li
     * @date 2022/11/18 09:36
     */
    @Override
    public boolean courseOffShell(Integer coursePackageId) {
        LambdaQueryWrapper<CoursePackage> wrapper=new LambdaQueryWrapper();
        wrapper.eq(CoursePackage::getId, coursePackageId);
        wrapper.eq(CoursePackage::getIsDeleted,0);
        CoursePackage coursePackage = dao.selectOne(wrapper);
        if (ObjectUtil.isEmpty(coursePackage)){
            throw new VcaException("该套课不存在");
        }
        coursePackage.setStatus(0);
        return transactionTemplate.execute(e->{
            dao.updateById(coursePackage);
            return Boolean.TRUE;
        });
    }

    /**
     * 获取所有套课的时长
     *
     * @return
     * @author Li
     * @date 2022/11/18 10:00
     */
    @Override
    public List<BigDecimal> getDurationTotal() {
        LambdaQueryWrapper<CoursePackage> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(CoursePackage::getIsDeleted,0);
        List<CoursePackage> coursePackages = dao.selectList(wrapper);
        List<BigDecimal> durationTotal = coursePackages.stream().map(CoursePackage::getDurationTotal).distinct().collect(Collectors.toList());
        return durationTotal;
    }

    /**
     * 添加套课
     *
     * @param request
     * @return
     * @author Li
     * @date 2022/11/18 10:11
     */
    @Override
    public boolean addCoursePackage(CoursePackageAddRequest request) {
        List<Course> list = courseService.list(new LambdaQueryWrapper<Course>()
                .in(Course::getId, request.getCourseIds()).eq(Course::getIsDeleted, 0));
        if (ObjectUtil.isEmpty(list)){
            throw new VcaException("添加的课程不存在");
        }
        CoursePackage coursePackage=new CoursePackage();
        BeanUtils.copyProperties(request,coursePackage);
        coursePackage.setStatus(0);
        if (ObjectUtil.isEmpty(coursePackage.getSort())){
            coursePackage.setSort(0);
        }
        //去除阿里云前缀
        coursePackage.setCoverImage(systemAttachmentService.clearPrefix(request.getCoverImage()));
        List<String> carouselCharts=new ArrayList();
        request.getCarouselChart().forEach(e->{
            carouselCharts.add(systemAttachmentService.clearPrefix(e));
        });
        coursePackage.setDetails(systemAttachmentService.clearPrefix(request.getDetails()));
        coursePackage.setDetailsEn(systemAttachmentService.clearPrefix(request.getDetailsEn()));
        coursePackage.setCarouselChart(JSONArray.parseArray(JSON.toJSONString(carouselCharts)).toJSONString());
        coursePackage.setMainPictureVideo(systemAttachmentService.clearPrefix(request.getMainPictureVideo()));
        coursePackage.setSharePoster(systemAttachmentService.clearPrefix(request.getSharePoster()));
        coursePackage.setDurationTotal(new BigDecimal(request.getDurationTotal()));
        List<CourseAbout> courseAboutList=new ArrayList();
        Map<Integer, List<CourseAboutAddRequest>> listMap = request.getCourseAboutAddRequests().stream().collect(Collectors.groupingBy(e->e.getTypeCourse()));

        //验证判断添加的相关课程和商品是否存在
        courseAboutService.checkWhetherCourseAbout(listMap);

        //事务
        return transactionTemplate.execute(e->{
            //添加套课并获得 套课id
            save(coursePackage);
            List<CoursePackageRelation> coursePackageRelations=new ArrayList();
            //添加套课和相关课程或商品的关系
            request.getCourseAboutAddRequests().forEach(g->{
                CourseAbout courseAbout=new CourseAbout();
                BeanUtils.copyProperties(g,courseAbout);
                if(ObjectUtil.isEmpty(g.getSort())){
                    courseAbout.setSort(0);
                }
                courseAbout.setAboutMainId(coursePackage.getId());
                courseAbout.setTypeMainCourse(1);
                courseAboutList.add(courseAbout);
            });
            courseAboutService.addCourseAboutList(courseAboutList);
            //添加套课与课程的关系
            request.getCourseIds().forEach(g->{
                CoursePackageRelation  coursePackageRelation=new CoursePackageRelation();
                coursePackageRelation.setCourseId(g);
                coursePackageRelation.setCoursePackageId(coursePackage.getId());
                coursePackageRelations.add(coursePackageRelation);
            });
            coursePackageRelationService.addCoursePackageRelation(coursePackageRelations);
            return Boolean.TRUE;
        });
    }

    /**
     * 根据id获取课程信息
     *
     * @param courseId
     * @return
     * @author Li
     * @date 2022/11/22 16:29
     */
    @Override
    public CoursePackageAdminResponse getCourse(Long courseId) {
        CoursePackageAdminResponse response=new CoursePackageAdminResponse();
        //查询课程是否存在
        LambdaQueryWrapper<CoursePackage> wrapper=new LambdaQueryWrapper();
        wrapper.eq(CoursePackage::getId, courseId);
        wrapper.eq(CoursePackage::getIsDeleted,0);
        CoursePackage coursePackage = dao.selectOne(wrapper);
        if (ObjectUtil.isEmpty(coursePackage)) {
            throw new VcaException("课程不存在");
        }
        List<CoursePackageAdminResponse.CourseRelation> courseRelations=new ArrayList<>();
        List<CoursePackageRelation> coursePackageRelations = coursePackageRelationService.list(new LambdaQueryWrapper<CoursePackageRelation>().eq(CoursePackageRelation::getCoursePackageId, courseId));
        Map<String, List<HashMap<String, Object>>> courseAdminConfig = systemGroupDataService.getCourseAdminConfig();
        List<HashMap<String, Object>> price = courseAdminConfig.get("priceList");
        List<HashMap<String, Object>> address = courseAdminConfig.get("addressList");
        List<HashMap<String, Object>> duration = courseAdminConfig.get("durationList");
        coursePackageRelations.forEach(e->{
            CoursePackageAdminResponse.CourseRelation courseRelation=new CoursePackageAdminResponse.CourseRelation();
            courseRelation.setId(e.getCourseId());
            Course course = courseService.getOne(new LambdaQueryWrapper<Course>().eq(Course::getId, e.getCourseId()).eq(Course::getIsDeleted, 0));
            courseRelation.setName(course.getName());
            courseRelation.setCoverImage(course.getCover());
            //获得地址信息
            address.forEach(g -> {
                Map map = JSON.parseObject(JSONObject.toJSONString(g), Map.class);
                if (map.get("id").equals(course.getCourseAddressId())) {
                    courseRelation.setCourseAddress(map.get("courseAddress").toString() + map.get("courseAddressInfo").toString());
                }
            });
            duration.forEach(g->{
                Map map = JSON.parseObject(JSONObject.toJSONString(g), Map.class);
                if (map.get("id").equals(course.getCourseDurationId())) {
                    courseRelation.setCourseDuration(map.get("courseDuration").toString());
                }
            });
            courseRelations.add(courseRelation);
        });
        BeanUtils.copyProperties(coursePackage,response);
        response.setDurationTotal(coursePackage.getDurationTotal().toString());
        List<CourseAbout> courseAbouts = courseAboutService.list(new LambdaQueryWrapper<CourseAbout>().eq(CourseAbout::getAboutMainId, courseId).eq(CourseAbout::getIsDeleted, 0).eq(CourseAbout::getTypeMainCourse,1));
        //将相关课程和商品根据0 = 课程 1=讲座 2=展览 3=商品 4=套课
        Map<Integer, List<CourseAbout>> listMap = courseAbouts.stream().collect(Collectors.groupingBy(e->e.getTypeCourse()));
        //验证判断添加的相关课程和商品是否存在
        //获得价格
        price.forEach(e -> {
            Map map = JSON.parseObject(JSONObject.toJSONString(e), Map.class);
            if (map.get("id").equals(coursePackage.getCoursePackagePriceId())) {
                response.setPrice(map.get("coursePrice").toString());
            }
        });
        //获得相关课程的信息
        List<CourseAboutAdminResponse> aboutList = courseAboutService.getAdminCourseAbout(listMap, courseAdminConfig);
        response.setCourseAboutAdminResponses(aboutList);
        response.setCourseRelations(courseRelations);
        return response;
    }

    /**
     * @param request
     * @Description:修改课程
     * @Author: Li
     * @Date: 2022/11/22 16:29
     */
    @Override
    public boolean updateCourse(CoursePackageAddRequest request) {
        List<Course> list = courseService.list(new LambdaQueryWrapper<Course>()
                .in(Course::getId, request.getCourseIds()).eq(Course::getIsDeleted, 0)
                .eq(Course::getIsRecycle, 0).eq(Course::getStatus, 1));
        if (ObjectUtil.isEmpty(list)) {
            throw new VcaException("添加的课程不存在");
        }
        CoursePackage coursePackage = dao.selectOne(new LambdaQueryWrapper<CoursePackage>()
                .eq(CoursePackage::getId, request.getId()).eq(CoursePackage::getIsDeleted, 0));
        if (ObjectUtil.isEmpty(coursePackage)) {
            throw new VcaException("修改的套课不存在");
        }
        BeanUtils.copyProperties(request, coursePackage);
        coursePackage.setStatus(0);
        if (ObjectUtil.isEmpty(coursePackage.getSort())) {
            coursePackage.setSort(0);
        }
        //去除阿里云前缀
        coursePackage.setDetails(systemAttachmentService.clearPrefix(request.getDetails()));
        coursePackage.setDetailsEn(systemAttachmentService.clearPrefix(request.getDetailsEn()));
        coursePackage.setCoverImage(systemAttachmentService.clearPrefix(request.getCoverImage()));
        List<String> carouselCharts = new ArrayList();
        request.getCarouselChart().forEach(e -> {
            carouselCharts.add(systemAttachmentService.clearPrefix(e));
        });
        coursePackage.setCarouselChart(JSONArray.parseArray(JSON.toJSONString(carouselCharts)).toJSONString());
        coursePackage.setMainPictureVideo(systemAttachmentService.clearPrefix(request.getMainPictureVideo()));
        coursePackage.setSharePoster(systemAttachmentService.clearPrefix(request.getSharePoster()));
        List<CourseAbout> courseAboutList = new ArrayList();
        request.getCourseAboutAddRequests().forEach(g -> {
            CourseAbout courseAbout = new CourseAbout();
            BeanUtils.copyProperties(g, courseAbout);
            if(ObjectUtil.isEmpty(g.getSort())){
                courseAbout.setSort(0);
            }
            courseAbout.setAboutMainId(request.getId());
            courseAbout.setTypeMainCourse(1);
            if (ObjectUtil.isNotEmpty(g.getCourseAboutId())){
                courseAbout.setId(g.getCourseAboutId());
            }
            courseAboutList.add(courseAbout);
        });
        Map<Integer, List<CourseAboutAddRequest>> listMap = request.getCourseAboutAddRequests().stream().collect(Collectors.groupingBy(e -> e.getTypeCourse()));

        //验证判断添加的相关课程和商品是否存在
        courseAboutService.checkWhetherCourseAbout(listMap);

        //事务
        return transactionTemplate.execute(e -> {
            //添加套课并获得 套课id
            updateById(coursePackage);
            List<CoursePackageRelation> coursePackageRelations = new ArrayList();
            courseAboutService.updateCourseAboutList(courseAboutList, coursePackage.getId());
            //添加套课与课程的关系
            request.getCourseIds().forEach(g -> {
                CoursePackageRelation coursePackageRelation = new CoursePackageRelation();
                coursePackageRelation.setCourseId(g);
                coursePackageRelation.setCoursePackageId(coursePackage.getId());
                coursePackageRelations.add(coursePackageRelation);
            });
            coursePackageRelationService.updateCoursePackageRelation(coursePackageRelations, coursePackage.getId());
            return Boolean.TRUE;
        });
    }

    /**
     * 获得课程头部数据
     *
     * @return
     * @author Li
     * @date 2022/11/23 09:16
     */
    @Override
    public List<AdminHeaderResponse> getHeader() {
        List<AdminHeaderResponse> headers=new ArrayList();
        AdminHeaderResponse active=new AdminHeaderResponse(0,"Active",1,null);
        AdminHeaderResponse inActive=new AdminHeaderResponse(0,"InActive",0,null);
        active.setCount(dao.selectList(new LambdaQueryWrapper<CoursePackage>().eq(CoursePackage::getStatus,1).eq(CoursePackage::getIsDeleted,0)).size());
        inActive.setCount(dao.selectList(new LambdaQueryWrapper<CoursePackage>().eq(CoursePackage::getStatus,0).eq(CoursePackage::getIsDeleted,0)).size());
        headers.add(active);
        headers.add(inActive);
        return headers;
    }

    /**
     * 删除套课
     *
     * @param courseId
     * @return
     * @author Li
     * @date 2022/11/23 09:16
     */
    @Override
    public boolean deleteCourse(Long courseId) {
        CoursePackage coursePackage = dao.selectOne(new LambdaQueryWrapper<CoursePackage>()
                .eq(CoursePackage::getId, courseId).eq(CoursePackage::getIsDeleted, 0));
        if (ObjectUtil.isEmpty(coursePackage)) {
            throw new VcaException("修改的套课不存在");
        }
        List<CourseAbout> abouts = courseAboutService.list(new LambdaQueryWrapper<CourseAbout>().eq(CourseAbout::getAboutMainId, courseId).eq(CourseAbout::getIsDeleted, 0));
        coursePackage.setIsDeleted(1);
        return transactionTemplate.execute(e->{
            courseAboutService.delByids(abouts.stream().map(CourseAbout::getId).collect(Collectors.toList()));
            dao.update(coursePackage,new LambdaUpdateWrapper<CoursePackage>().eq(CoursePackage::getId,courseId).set(CoursePackage::getIsDeleted,1));
            return Boolean.TRUE;
        });
    }

    @Override
    public List<CoursePackage> getCoursePackagesAndDelete(List<Long> ids) {
        return dao.getCoursePackages(ids);
    }
}
